package com.wkbb.basic.thread;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.wkbb.common.config.ServiceConfig;
import com.wkbb.common.utils.ThreadPoolUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * @author dengjingyuan
 * 创建时间：2020-06-30 15:58
 */
@Slf4j
@Data
public class BasicThreadPoolUtil {

    /**
     * 线程池默认阻塞队列默认值 （分两步：1第一次满的时候开启最大线程数 2第二次满的时候启用拒绝策略 默认为200）
     */
    private Integer maxBlockingQueueSize;

    /**
     * 最大线程活跃时间(单位：秒)
     */
    private volatile Long keepAliveTime;

    /**
     * 线程池初始化大小，默认为cpu核数
     */
    private volatile Integer corePoolSize;

    /**
     * 线程池维护线程的最大数量
     * 1、CPU密集型：操作内存处理的业务，一般线程数设置为：CPU核数 + 1 或者 CPU核数*2。核数为4的话，一般设置 5 或 8
     * 2、IO密集型：文件操作，网络操作，数据库操作，一般线程设置为：cpu核数 / (1-0.9)，核数为4的话，一般设置 40
     */
    private volatile Integer maxPoolSize;//放大2倍

    /**
     * 线程池
     */
    private volatile static ExecutorService executorService = null;

    private static BasicThreadPoolUtil basicThreadPoolUtil ;

    private BasicThreadPoolUtil() {
    }

    public static BasicThreadPoolUtil getBasicThreadPoolUtil() {
        if(null==basicThreadPoolUtil){
               synchronized (BasicThreadPoolUtil.class){
                   if(null==basicThreadPoolUtil){
                       basicThreadPoolUtil=new BasicThreadPoolUtil();
                   }
               }
        }
        return basicThreadPoolUtil;
    }

/*    public BasicThreadPoolUtil (ServiceConfig serviceConfig) {
        maxBlockingQueueSize=serviceConfig.getBasicMaxBlockingQueueSize();
        keepAliveTime=serviceConfig.getBasicKeepAliveTime();
        corePoolSize=serviceConfig.getBasicCorePoolSize();
        maxPoolSize=serviceConfig.getBasicMaxPoolSize();
    }*/
    /**
     * 单例模式创建唯一的线程池
     *
     * @return 线程池对象
     */
    public static ExecutorService getExecutorService(BasicThreadPoolUtil basicThreadPoolUtil) {
        if (executorService == null) {
            synchronized (ThreadPoolUtil.class) {
                if (executorService == null) {
                    log.info("线程池初始化....CORE_POOL_SIZE:{},MAX_POOL_SIZE:{},KEEP_ALIVE_TIME:{},MAX_BLOCKING_QUEUE_SIZE:{}", basicThreadPoolUtil.getCorePoolSize(), basicThreadPoolUtil.getMaxPoolSize(), basicThreadPoolUtil.getKeepAliveTime(), basicThreadPoolUtil.getMaxBlockingQueueSize());
                    ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("wkbb-thread-pool-%d").build();
                    executorService = new ThreadPoolExecutor(basicThreadPoolUtil.getCorePoolSize(), basicThreadPoolUtil.getMaxPoolSize(), basicThreadPoolUtil.getKeepAliveTime(),
                            TimeUnit.SECONDS, new LinkedBlockingQueue<>(basicThreadPoolUtil.getMaxBlockingQueueSize()),
                            namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
                }
            }
        }
        return executorService;
    }

    /**
     * 提交线程池任务
     *
     * @param runnable 线程类
     */
    public static void addPoolTask(Runnable runnable) {
        ExecutorService executorService = getExecutorService(basicThreadPoolUtil);
        executorService.submit(runnable);
    }

    /**
     * 提交线程池任务
     *
     * @param callable 异步线程类
     */
    public static <T> Future<T> addPoolTask(Callable<T> callable) {
        ExecutorService executorService = getExecutorService(basicThreadPoolUtil);
        return executorService.submit(callable);
    }
}
